﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ScreenRuler
{
    public partial class Ruler : Form
    {
        public Ruler()
        {
            InitializeComponent();
            this.Opacity = Properties.Settings.Default.Opacity;
            this.Size = Properties.Settings.Default.RulerSize;
            this.BackColor = Properties.Settings.Default.BGColor;
            this.PrepareBGImage();
            new FormDragger(this);
        }

        RatioCalculator Setting = new RatioCalculator();

        private void Ruler_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch (e.KeyChar)
            {
                case '\r':
                    this.SwitchFullScreen();
                    break;
                case '':
                    this.Close();
                    break;
                default:
                    break;
            }
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            this.Opacity = 1.0;
            Properties.Settings.Default.Opacity = this.Opacity;
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            this.Opacity = 0.8;
            Properties.Settings.Default.Opacity = this.Opacity;
        }

        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            this.Opacity = 0.6;
            Properties.Settings.Default.Opacity = this.Opacity;
        }

        private void toolStripMenuItem5_Click(object sender, EventArgs e)
        {
            this.Opacity = 0.4;
            Properties.Settings.Default.Opacity = this.Opacity;
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            this.Opacity = 0.2;
            Properties.Settings.Default.Opacity = this.Opacity;
        }

        private void ratioSettingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.Setting.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Properties.Settings.Default.LenthInMMPerPixel = this.Setting.LengthInMMPerPixel;
                this.PrepareBGImage();
            }
        }

        private void Ruler_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            Properties.Settings.Default.Opacity = this.Opacity;
            Properties.Settings.Default.RulerSize = this.Size;
            Properties.Settings.Default.BGColor = this.BackColor;
            Properties.Settings.Default.Save();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void fillScreenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.SwitchFullScreen();
        }

        private void SwitchFullScreen()
        {
            if (this.WindowState != FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Maximized;
                this.fillScreenToolStripMenuItem.Text = "NormalSize";
            }
            else
            {
                this.WindowState = FormWindowState.Normal;
                this.fillScreenToolStripMenuItem.Text = "FillScreen";
            }
        }

        private void topMostToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.TopMost = !this.TopMost;
        }

        private void backColorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.BackColor = this.colorDialog.Color;
            }
        }

        private void PrepareBGImage()
        {
            Size ScreenArea = Screen.PrimaryScreen.Bounds.Size;
            Bitmap bmp = new System.Drawing.Bitmap(
                ScreenArea.Width, ScreenArea.Height,
                System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            float dpi = (float)(25.4 / Properties.Settings.Default.LenthInMMPerPixel);
            bmp.SetResolution(dpi, dpi);
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            g.PageUnit = GraphicsUnit.Millimeter;
            g.Clear(System.Drawing.Color.FromArgb(0, 0, 0, 0));

            this.DrawRulers(g);
            g.Dispose();

            Image old = this.BackgroundImage;
            this.BackgroundImage = bmp;
            if (old != null)
            {
                old.Dispose();
            }
        }

        private void DrawRulers(Graphics G)
        {
            Pen p = new Pen(Color.Black, 0.1f);
            Font f = new Font("Times New Roman", 12);
            Brush b = new SolidBrush(Color.Black);
            for (int i = 0; i < G.VisibleClipBounds.Width; i++)
            {
                if (i % 10 == 0)
                {
                    G.DrawLine(p, i, 0, i, 5);
                    G.DrawString((i / 10).ToString(), f, b, i, 5);
                }
                else if(i % 5 == 0)
                {
                    G.DrawLine(p, i, 0, i, 3);
                }
                else
                {
                    G.DrawLine(p, i, 0, i, 1.5f);
                }
            }
            for (int i = 0; i < G.VisibleClipBounds.Height; i++)
            {
                if (i % 10 == 0)
                {
                    G.DrawLine(p, 0, i, 5, i);
                    G.DrawString((i / 10).ToString(), f, b, 5, i);
                }
                else if (i % 5 == 0)
                {
                    G.DrawLine(p, 0, i, 3, i);
                }
                else
                {
                    G.DrawLine(p, 0, i, 1.5f, i);
                }
            }

            //Draw the angel ruler
            float AngelRulerHeight = Math.Min(G.VisibleClipBounds.Width/2, G.VisibleClipBounds.Height) - 15;
            RectangleF r = new RectangleF(15, G.VisibleClipBounds.Height - 10 - AngelRulerHeight,
                2 * AngelRulerHeight, AngelRulerHeight);
            G.DrawLine(p, r.Left, r.Bottom, r.Right, r.Bottom);
            G.DrawArc(p, r.Left, r.Top, r.Width, r.Height * 2, 180, 180);
            G.DrawArc(p, r.Left + 30, r.Top + 30, r.Width - 60, r.Height * 2 - 60, 180, 180);
            G.DrawArc(p, r.Left + 60, r.Top + 60, r.Width - 120, r.Height * 2 - 120, 180, 180);
            PointF Center = new PointF(r.Left + AngelRulerHeight, r.Bottom);
            for (int i = 0; i <= 180; i++)
            {
                double Degree = i / 180.0 * Math.PI;
                float XRatio = -(float)Math.Cos(Degree);
                float YRatio = -(float)Math.Sin(Degree);
                PointF Start = PointF.Add(
                    Center, new SizeF(AngelRulerHeight * XRatio, AngelRulerHeight * YRatio));
                PointF End;
                if (i % 30 == 0)
                {
                    End = Center;
                    PointF NumberPoint = PointF.Add(Center, new SizeF((AngelRulerHeight - 8) * XRatio, (AngelRulerHeight - 8) * YRatio));
                    G.DrawString(i.ToString(), f, b, NumberPoint);
                }
                else if (i % 10 == 0)
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 8) * XRatio, (AngelRulerHeight - 8) * YRatio));
                    G.DrawString(i.ToString(), f, b, End);
                }
                else if (i % 5 == 0)
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 4) * XRatio, (AngelRulerHeight - 4) * YRatio));
                }
                else
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 2) * XRatio, (AngelRulerHeight - 2) * YRatio));
                }
                G.DrawLine(p, Start, End);

                if (AngelRulerHeight < 30)
                {
                    return;
                }
                Start = PointF.Add(
                    Center, new SizeF((AngelRulerHeight-30) * XRatio, (AngelRulerHeight-30) * YRatio));
                if (i % 10 == 0)
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 38) * XRatio, (AngelRulerHeight - 38) * YRatio));
                }
                else if (i % 5 == 0)
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 34) * XRatio, (AngelRulerHeight - 34) * YRatio));
                }
                else
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 32) * XRatio, (AngelRulerHeight - 32) * YRatio));
                }
                G.DrawLine(p, Start, End);

                if (AngelRulerHeight < 60)
                {
                    return;
                }
                Start = PointF.Add(
                    Center, new SizeF((AngelRulerHeight - 60) * XRatio, (AngelRulerHeight - 60) * YRatio));
                if (i % 10 == 0)
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 68) * XRatio, (AngelRulerHeight - 68) * YRatio));
                }
                else if (i % 5 == 0)
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 64) * XRatio, (AngelRulerHeight - 64) * YRatio));
                }
                else
                {
                    End = PointF.Add(Center, new SizeF((AngelRulerHeight - 62) * XRatio, (AngelRulerHeight - 62) * YRatio));
                }
                G.DrawLine(p, Start, End);
            }
        }
    }
}
